<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <style>
        .test{
            color: black;
            height: 29px;
        }
    </style>
    <title>example</title>
</head>
<body>

<!--控制器声明-->
<div jq-controller="index.controller">
    <!--依赖注入测试-->
    <button class="but" type="button">jqPlus</button>
    <!--指令测试-->
    <my-form></my-form>
    <!--双向绑定器测试-->
    <input type="text" class="doubleBind" placeholder="双向绑定器">
    <input type="text" class="test" placeholder="双向绑定器">
    <p class="test"></p>
</div>

<script type="text/javascript" src="lib/jquery.min.js"></script>
<script type="text/javascript" src="jqPlus.js"></script>

<script>

    //配置框架功能
    jqPlus.config({
        double: true, //双向绑定功能
        watch: true, //监听功能
        directive: true,  //指令功能
        inject: true,  //依赖注入功能
        ajax: true  //ajax打开这个功能将删除jquery ajax
    });

    //声明注入文件模块名称
    inject.config({
        layer: 'layer.js',  //声明layer,和文件位置
        example: 'example.js'   //声明example,和文件位置
    });

    new jqPlus.bootstrap;

    /*
    * 命名空间
    * 控制器
    * 服务
    * */
    namespace('index').controller = 'index.controller';  //声明控制器
    namespace('index').service = 'index.service';  //声明服务

    //服务 用来存储事件和业务逻辑
    index.service = Class.extend({
        clickAction: function(){
            //this.scope => scope: ['example','layer']
            this.scope.example.mysql(); // => example
            this.scope.layer.alert(123);  // => layer
        }
    });

    //VM（控制器）用来绑定数据和模型，VM（控制器）依赖于服务service
    index.controller = index.service.extend({
        //声明依赖注入,之后可以在service里调用方法，依赖注入外的范围无法访问js功能。
        //inject: false, || inject: [] || 不定义inject 就关闭了依赖注入功能 inject将无法写入
        inject: ['example','layer'],
        //变量设置
        $button: null,
        //这里写入绑定VM（控制器）
        init: function(){
            this.$button = $('.but');
            //运行事件绑定和依赖注入
            this._super();
        },
        //事件绑定
        addListener: function(){
            //事件绑定
            this.$button.click(this.clickAction.bind(this));
        }
    });

    //这里无法访问layer依赖注入可以不去污染其他环境
    setTimeout(function(){
        console.log('layer:' + typeof layer);
    },3000);

    //实例化VM
    new index.controller;

    //指令
    /*
    * name: 指令名称 ==> name: 'my-form',调用方式<my-form></my-form>
    * templateUrl: 指令html模板位置,templateUrl和template两个都定义默认为templateUrl
    * template：直接定义模板,templateUrl和template两个都定义默认为templateUrl
    * controller：模板指令控制器返回vm参数，数据绑定器
    * */
    jqPlus.directive({
        name: 'my-form',  //标签名称
        compile: true,  //是否开启模板引擎，模板引擎可以减少譬如 <div> + + ...这种方式可以用来绑定数据用
        replace: true,  //需不需要移除原先的name（my-form）标签，Boolean，false代表不移除，true代表移除,为了不去污染原生html标签可以令自定义标签移除
        templateUrl: 'myForm.html', // 远程模板,templateUrl和template两个都定义默认为templateUrl
        template: '<div>{{title}}</div>',  //直接定义模板,templateUrl和template两个都定义默认为templateUrl
        controller: function(vm){  //控制器，vm为数据绑定器
            //绑定数据,vm.template给模板绑定数据
            vm.template = {
                admin: true,
                title: '标签',
                list: ['文艺', '博客', '摄影', '电影', '民谣', '旅行', '吉他']
            };
            //绑定事件
            $(".liIndex").click(function(){
                alert($(this).html());
            });
            //绑定事件
            $(".submit").click(function(){
                //提交form表单
                jqPlus.ajax({
                    async: true,
                    method: 'post',
                    url: '/model',
                    data: {
                        formData: '#myForm'
                    }
                }).then(function(data){
                    console.log(data);
                }).fail(function(err){
                    console.error(err);
                });
            })
        }
    });

    //监听对象变化
    //watchCode('监听obj','监听对象',回调函数(对象写入set/对象读取get,'写入的新对象数据'))
    var myObj = {
        name: 1
    };

    //监听数据写入
    /*参数
    * 被监听obj
    * 被监听obj下的参数
    *
    * */
    jqPlus.watchCode(myObj,'name',function(act,newValue,oldValue){
        if(act == 'get') {
            act = '读取';
        }
        else if(act == 'set') {
            act = '写入';
        }
        //可以被监听对象值变化，可以监听set和get变化       （set可监听重写）
        //但无法监听对象下的孩子的数值set变化，只能监听到get （set不可监听修改）
        console.log('myObj.name被监听修改，事件: ' + act);
        if(newValue){
            console.log(newValue,oldValue);
        }
    });

    setTimeout(function(){
        //修改数据
        myObj.name = new Object;
        //读取数据
        myObj.name = {            //可以被监听对象值变化，可以监听set和get变化       （set可监听重写）
            myAge: 4321
        };
        myObj.name.myAge = 1234;  //但无法监听对象下的孩子的数值set变化，只能监听到get （set不可监听修改）
    },1500);


    //脏值检查(对象强监控)
    //eg1
    var objName = {
        name: [1,2],
        user: {
            mine: 1
        }
    };

    jqPlus.observe(objName, "objName",["name","user"], function (name, value, oldValue) {
        console.log(name, value, oldValue);
    });

    //重写触发监听
    objName.name = [3,4];
    objName.user = {
        mine: {}
    };

    //eg2
    //声明新的嵌套对象
    $observe('objName.user.home',12345);
    objName.user.home = 2;

    //输入框双向绑定
    //doubleBind('输入框选择器','输入框选择器','callback(newValue)');
    jqPlus.doubleBind($('.doubleBind'),$('.test'),function(newValue){
        console.log(newValue);
    });

    //ajax 返回promise
    /*
    * {Boolean}  async是否开启异步默认为true
    * {method}   method: 'GET', 请求
    * {url}      url: 'model/12'路径
    * {all}      data{
    *                  param    main序列化开关
    *                  main     需要提交的数据
    *                  formData 需要提交的表单
    *                }
    * {number}   timeout: 最大延迟时间  ie8+
    * {Array || true}    cache 缓存  Array缓存键值，true为默认缓存
    * {Boolean}  localStorage   将cache的键值存入localStorage
    * {Boolean}  sessionStorage 将cache的键值存入sessionStorage
    * {Boolean}  globalStorage  将cache的键值存入globalStorage
    * {Json}     headers头部
    * {Json}     params url?=params
    * {function} loadStart ajax开始触发函数
    * {function} progress 接受响应期间触发
    * {function} error 错误触发
    * {function} abort 终止触发
    * {function} load 接受完整数据触发
    * {function} loadEnd 完成ajax触发
    * */
    //普通请求
    jqPlus.ajax({
        async: true,
        method: 'post',   //增加double和push
        url: '/model',
        data: {
            param: true,
            main: {my1: '1', my2: '2'}
        },
        timeout: 1000,
        cache: ['myCache1','myCache2'],
        localStorage: true,
        sessionStorage: true,
        globalStorage: true,
        headers: {'Content-Type': 'application/x-www-form-urlencoded'},
        params: {my1: '1', my2: '2'},
        loadStart: function(d){console.log(d)},
        progress: function(d){console.log(d)},
        error: function(d){console.log(d)},
        abort: function(d){console.log(d)},
        load: function(d){console.log(d)},
        loadEnd: function(d){console.log(d)}
    }).then(function(data){
        console.log(data);
    }).fail(function(err){
        console.error(err);
    });

    //服务器推送请求，服务器推送无法支持promise
    jqPlus.ajax({
        method: 'PUSH',   //增加double和push
        url: '/PUSH'
    },function(data){
        console.log(data);
    });

    //数组继承
    namespace('nameFac1').Fac = 'nameFac.Fac';
    nameFac1.Fac = arrayExtend.extend({
        myArrayExtend1: null,
        myScope1: function(){
            this.myArrayExtend1 = '继承自1';
        }
    });

    namespace('nameFac2').Fac = 'nameFac2.Fac';
    nameFac2.Fac = arrayExtend.extend({
        myArrayExtend2: null,
        myScope2: function(){
            this.myArrayExtend2 = '继承自2';
        }
    });

    var mn = jqPlus.returnArrayExtend([nameFac1.Fac,nameFac2.Fac]).extend({
        init: function(){
            this.myScope1();
            this.myScope2();
            console.log(this.myArrayExtend1);
            console.log(this.myArrayExtend2);
        }
    });

    new mn;

    //ajax拦截器
    jqPlus.interceptor = {
        //拦截请求
        request: function(data){
            console.log(data);
            //返回请求，当中可以设置请求
            return data;
        },
        //拦截响应
        response: function(){},
        //拦截请求失败
        requestError: function(){},
        //拦截响应失败
        responseError: function(){}
    };

    //测试


</script>

</body>
</html>